unit MainDM;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, FileUtil, LResources, DB,
  QueryConditions, DataRecord;

type

  TMDState = (mdsCanEdit, mdsCanInsert, mdsEditing, mdsDisable);
  { TMainDataModule }

  /// Módulo de dados principal
  TMainDataModule = class(TDataModule)
  private
    /// DataSet Principal
    FMainDataSet: TDataSet;
  public
    /// Abre o DataSet
    procedure Insert(); virtual;
    /// Coloca o DataSet em modo de edição
    procedure Edit(); virtual;
    /// Deleta o registro atual do DataSet
    procedure Delete(); virtual;
    /// Confirma as alterações para o DataSet
    procedure Post(); virtual;
    /// Cancela as alterações no DataSet
    procedure Cancel(); virtual;
    /// DataSet Principal
    property MainDataSet: TDataSet read FMainDataSet write FMainDataSet;
    /// Abre o DataSet
    procedure OpenDataSet(); virtual; abstract;
    /// Fecha o DataSet
    procedure CloseDataSet(); virtual; abstract;
    /// Realiza busca (método abstrato)
    /// @param(Condicoes são as condições para a busca)
    /// @param(Tabela é a tabela no banco de dados)
    procedure Search(Condicoes: TQueryConditions; Tabela: string); virtual; abstract;
    //! Se renomearmos os componentes como tabela0nome_campo, pode ser possível implementar este método aqui
    /// Retorna o estado do dataset
    /// @return(Retorna:
    ///         mdsCanEdit se o DataSet pode ser editado
    ///         mdsCanInsert se o DataSet pode receber inserções
    ///         mdsEditing se o DataSet está sendo editado
    ///         mdsDisable se o DataSet está desabilitado ou não existe)
    function DataSetState(): TMDState;
    /// Obtém um DataRecord com os dados do resitro atual do DataSet
    function GetDataRecord(): TDataRecord; virtual;
    /// Atribui um DataRecord aos dados atuais do DataSet
    /// @param(Data é o DataRecod com os dados que serão atributídos)
    procedure SetDataRecord(Data: TDataRecord);
    ///! Comentar
    function InTransaction(): boolean;
  end;

implementation

uses
  ZAbstractDataset;

{ TMainDataModule }

procedure TMainDataModule.Insert;
begin
  // Verifica se o módulo de dados possui um MainDataSet
  if (MainDataSet <> nil) then
    // Coloca o MainDataSet em modo de inserção;
    MainDataSet.Insert();
end;

procedure TMainDataModule.Edit;
begin
  // Verifica se o módulo de dados possui um MainDataSet e se há registros no mesmo
  if (MainDataSet <> nil) and (MainDataSet.RecordCount > 0) then
    // Coloca o MainDataSet em modo de edição;
    FMainDataSet.Edit();
end;

procedure TMainDataModule.Delete;
begin
  // Verifica se o módulo de dados possui um MainDataSet e se há registros no mesmo
  if (MainDataSet <> nil) and (MainDataSet.RecordCount > 0) then
    // Apaga o registro atual do MainDataSet
    FMainDataSet.Delete();
end;

procedure TMainDataModule.Post;
begin
  // Verifica se o módulo de dados possui um MainDataSet
  if (MainDataSet <> nil) then
    // Confirma as alterações no MainDataSet;
    FMainDataSet.Post();
end;

procedure TMainDataModule.Cancel;
begin
  // Verifica se o módulo de dados possui um MainDataSet
  if (MainDataSet <> nil) then
    // Cancela as alterações no MainDataSet
    FMainDataSet.Cancel();
end;

function TMainDataModule.DataSetState: TMDState;
begin
  // Verifica se o DataSet não existe e se está inativo
  if (MainDataSet = nil) or not (MainDataSet.Active) then begin
    // Se sim o retorna que o DataSet está desabilitado
    Result := mdsDisable;
  end else begin
    // Se não o dataser pode receber inserções
    Result := mdsCanInsert;
    // Testa se há ao menos um registro
    if (MainDataSet.RecordCount > 0) then begin
      // Retorna que o DataSet pode ser editado
      Result := mdsCanEdit;
    end;
    // Testa se o DataSet está em modo de edição e retorna
    if (MainDataSet.State in [dsEdit, dsInsert]) then begin
      Result := mdsEditing;
    end;
  end;
end;

function TMainDataModule.GetDataRecord: TDataRecord;
var
  Data: TDataRecord;
begin
  Data := nil;
  // Verifica se o módulo de dados possui um MainDataSet
  if (MainDataSet <> nil) then begin
    // Cria um DataRecord
    Data := TDataRecord.Create();
    // Inserr os dados do DataSet no DataRecord
    Data.ReadFromDataSet(MainDataSet);
  end;
  Result := Data;
end;

procedure TMainDataModule.SetDataRecord(Data: TDataRecord);
begin
  // Verifica se o módulo de dados possui um MainDataSet e se o DataRecord é válido
  if (MainDataSet <> nil) and (Data <> nil) then
    // Grava os dados do DataRecord no DataSet
    Data.WriteToDataSet(MainDataSet);
end;

function TMainDataModule.InTransaction(): boolean;
begin
  Result := TZAbstractDataset(MainDataSet).Connection.InTransaction;
end;

initialization
  {$I maindm.lrs}

end.
